#!/bin/sh
#
{ [ $# -lt 1 ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; } && {
	echo "Usage: sh $0 [-h] [--help] [install] [setup] [start] [reboot] [poweroff]"
	echo "    -h, --help    Show this help information."
	echo "    install       Install this file to folder /etc/finalrd/."
	echo "    setup         Called in finalrd.service by /usr/bin/finalrd."
	echo "    start         Called in initrd by /root/usr/share/debconf/confmodule."
	echo "    reboot        Called by in finalrd by /shutdown when system reboot."
	echo "    poweroff      Called by in finalrd by /shutdown when system poweroff."
	exit 1
}
[ "$1" = "install" ] && {
	d=/etc/finalrd; f=livecd.mounts.finalrd
	[ -e $d/$f ] || {
		mkdir -p $d && cp -av $f $d &&
		f=$d/$f && chmod 0755 $f && chown 0:0 $f || exit $?
	}
	#
	f=/root/etc/finalrd/livecd.mounts.finalrd
	t=/usr/share/debconf/confmodule
	tail $t | grep -q -e "f=$f" || {
		( echo ""; echo "f=$f && [ -e \$f ] && sh \$f start" ) |
			tee -a $t >/dev/null || exit $?
	}
	#
	exit 0
}
#
[ "$1" = "setup" ] && {
	# now run by /usr/bin/finalrd
	# systemctl cat finalrd.service
	# install executables in finalrd setup phase
	#
	# shellcheck source=/dev/null
	. /usr/share/initramfs-tools/hook-functions
	copy_exec /usr/bin/lsof
	copy_exec /usr/bin/mount
	copy_exec /usr/bin/grep
	copy_exec /usr/bin/umount
	copy_exec /usr/bin/mkdir
	copy_exec /usr/bin/sleep
	copy_exec /usr/bin/sync
	copy_exec /usr/bin/cat
	copy_exec /usr/bin/env
	copy_exec /usr/bin/ls
	copy_exec /usr/bin/ps
	copy_exec /usr/bin/pgrep
	copy_exec /usr/bin/kill
	copy_exec /usr/bin/tail
	copy_exec /usr/bin/mv
	copy_exec /usr/sbin/losetup
	copy_exec /usr/sbin/dmsetup
	copy_exec /usr/sbin/swapoff
	copy_exec /lib/systemd/systemd-shutdown.old /shutdown.old
	copy_exec /usr/bin/bash
	#copy_exec /usr/sbin/chroot
	#copy_exec /usr/bin/fusermount
	#copy_exec /usr/sbin/mount.ntfs
	#
{	set -xv +e; echo "$0" "$@"; pwd; env; cat /proc/swaps; cat /proc/mounts; losetup -a
	#
	dmesg -n7
	# swapoff all, reset zram
	swapoff -v -a
	for i in $(echo /sys/block/zram*); do
		i=${i##*/}
		{ [ -n "$i" ] && [ -e "/dev/$i" ]; } || continue
		echo 1 > /sys/block/"$i"/reset
		cat /sys/block/"$i"/backing_dev
	done
	# keep fusemount ntfs process mount.ntfs
	# echo y > /sys/module/fuse/parameters/allow_sys_admin_access
	# avoid to kill process mount.ntfs
	i=/run/sendsigs.omit.d;  j="$DESTROOTDIR"$i
	mkdir -p $i "$j"
	i=$i/ntfs-3g;  j="$j"/ntfs-3g
	( pidof mount.ntfs; pidof mount.ntfs-3g ) |
		tee -a $i "$j"
	grep -H -e . $i "$j"
	# force to remount all filesystems read-only
	#echo u > /proc/sysrq-trigger
	#
cat /proc/swaps; cat /proc/mounts; losetup -a; } 2>&1 | tee -a /dev/console
	#
	exit 0
}
#
[ "$1" = "start" ] && {
	# now run by /init in initramfs at boot
	#
	# do nothing when not in initrd
	o=cow; s=isodevice; w=writable-backing; h=home-rw-backing; m=/proc/mounts
	t=/media
	grep -e $t/$o -e $t/$s -e $t/$w -e $t/$h $m &&
		exit 0
	# now in initrd
	set -xv +e
	echo ""; echo "From cow file /usr/share/debconf/confmodule: " "$0" "$@"
	pwd; env
	# move mounts
	t=/root/media
	grep -e $t/$o -e $t/$s -e $t/$w -e $t/$h $m || {
		cat $m && losetup -a &&
		for b in $o $s $w $h \
			$(grep " /root " $m | grep -o -e "lowerdir=[^,]\+" |
				tr "=:" "\n" | tail -n +2); do
			d=$(grep -o " [/]\?${b}[^ ]*" $m) && d=${d# } &&
				[ -n "$d" ] && mkdir -p $t"$d" &&
				mount -v -o move "$d" $t"$d"
		done
	} || true
	# move /root/tmp/debconf.xxx
	# f=/tmp/debconf. && [ x"$f*"x != x"$(echo $f*)"x ] && { d=/root/tmp.rm && mkdir -p $d && mv -f $f* $d/; }
	#
	exit 0
}
#
# now in finalrd run by /shutdown at system reboot or poweroff
#set +e
#set -xv +e
echo "$0" "$@"
echo "PID=$$"
v=false
[ z"$-" != z"${-#*x}" ] && {
	v=true
	sleep 1
	pwd; env
	lsof -w /oldroot/ /oldroot/dev/ | grep -v "\.so\>"
	ps -fw --ppid 2 --pid 2 --deselect
	mount; losetup -a; losetup -l; dmsetup ls; cat /proc/swaps
}
# trigger deattaching all loops, useful for fusermount
losetup -v -D
# kill all processes using /oldroot
p=0
lsof -w /oldroot/ "$(d=/oldroot/dev/; [ -e $d ] && echo $d)" |
	grep -e "\sREG\s" | grep -v -e "\.so\>" | tail -n+2 |
	while read -r i j k; do
	[ "$p" = "$j" ] && continue
	p=$j
	echo "kill $j $k"
	kill "$j"
done
#
#umount -v -R /oldroot
# move mounts out of '/oldroot/"
for i in media/isodevice cdrom rofs media/writable-backing media/cow; do
	grep -e " /oldroot/$i " /proc/mounts || continue
	mkdir -p /$i
	mount -v -o move /oldroot/$i /$i
done
for i in $(echo /oldroot/media/*); do
	grep -e " $i " /proc/mounts || continue
	i=${i#/oldroot}
	mkdir -p "$i"
	mount -v -o move /oldroot"$i" "$i"
done
#
# umount
umount -v -R /oldroot
for i in /oldroot /media/cow /media/writable-backing /rofs \
	$(echo /media/*) /cdrom /media/isodevice /media/writable-backing \
	$(echo /media/*); do
	grep -e " $i " /proc/mounts || continue
	umount -v "$i"
done
umount -v -R /oldroot
$v && {
	echo "Before last try umount."
	#sh -i
}
# last try umount
for i in oldroot root cow writable-backing rofs root/cdrom cdrom \
	isodevice media/cow media/isodevice \
	media/writable-backing media/isodevice; do
	grep -e " /$i " /proc/mounts || continue
	umount -v -R /$i || umount -v -l /$i || umount -v -f /$i
done
sync
losetup -v -D
dmsetup -v remove_all
#
if $v; then
	lsof -w /oldroot/ /oldroot/dev/ | grep -v "\.so\>"
	ps -fw --ppid 2 --pid 2 --deselect
	mount; losetup -a; losetup -l; dmsetup ls; cat /proc/swaps
	sleep 1
	#
	echo "At end of livecd.mounts.finalrd"
	sh -i
else
	echo; echo
	( set -xv; mount; losetup -a; losetup -l; dmsetup ls; cat /proc/swaps )
	echo; echo; sleep 1
fi
#
#[ $# -gt 0 ] && [ "1" = "$$" ] && exec /shutdown.old "$@"
#
## forece reboot or poweroff
## https://docs.kernel.org/admin-guide/sysrq.html
#[ "reboot" = "$1" ] && echo b > /proc/sysrq-trigger
#[ "poweroff" = "$1" ] && echo o > /proc/sysrq-trigger
#
exit 0

